package com.icexxx.db_init;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.DbUtil;
import cn.hutool.db.ds.simple.SimpleDataSource;
import cn.hutool.db.sql.SqlExecutor;
import cn.hutool.system.OsInfo;

public class DbInit {
	public static String init(String username, String password, String driver, String host, Integer port,
			String database, String mysqlPath, String sqlPath, String character, String collate) {
		if (StrUtil.isBlank(username)) {
			username = "root";
		}
		if (StrUtil.isBlank(password)) {
			password = "123456";
		}
		if (StrUtil.isBlank(driver)) {
			driver = "com.mysql.cj.jdbc.Driver";
		}
		if (StrUtil.isBlank(host)) {
			host = "127.0.0.1";
		}
		if (StrUtil.isBlank(character)) {
			character = "utf8mb4";
		}
		if (StrUtil.isBlank(collate)) {
			collate = "utf8mb4_unicode_ci";
		}
		if (port == null) {
			port = 3306;
		}
		sqlPath = sqlPath.replace("\\", "/");
		mysqlPath = mysqlPath.replace("\\", "/");
		File sqlFile = new File(sqlPath);
		List<String> list = new ArrayList<>();
		if (sqlFile.isDirectory()) {
			File[] listFiles = sqlFile.listFiles();
			for (File file : listFiles) {
				if (file.isFile()) {
					if (file.getName().endsWith(".sql")) {
						String absolutePath = file.getAbsolutePath();
						absolutePath = absolutePath.replace("\\", "/");
						list.add(absolutePath);
					}
				}
			}
		} else {
			if (sqlPath.endsWith(".sql")) {
				list.add(sqlPath);
			}
		}
		String createDatabaseSql = "CREATE DATABASE ${database} CHARACTER SET ${character} COLLATE ${collate};";
		createDatabaseSql = createDatabaseSql.replace("${database}", database);
		createDatabaseSql = createDatabaseSql.replace("${character}", character);
		createDatabaseSql = createDatabaseSql.replace("${collate}", collate);
		mysqlPath = StrUtil.addSuffixIfNot(mysqlPath, "/");
		StringBuilder sb = new StringBuilder();
		if (CollUtil.isNotEmpty(list)) {
			for (String sqlItem : list) {
				String sql = "source " + sqlItem + ";";
				sb.append(sql);
			}
		}
		String baseCmd = mysqlPath + "mysql -h";
		if(mysqlPath.contains(" ")) {
			baseCmd = "\"" + mysqlPath + "mysql\" -h";
		}
		String cmd1 = baseCmd + host + " -u" + username + " -p" + password + " -P" + port + " -e \""
				+ createDatabaseSql + "\"";
		String cmd2 = baseCmd + host + " -u" + username + " -p" + password + " -P" + port + " -e \""
				+ "use " + database + ";" + sb.toString() + "\"";
		String[] cmdArrayCreateDatabase = { "/bin/sh", "-c", cmd1 };
		String[] cmdArrayImportSql = { "/bin/sh", "-c", cmd2 };
		OsInfo os = new OsInfo();
		if (os.isWindows()) {
			cmdArrayCreateDatabase = new String[] { "cmd.exe", "/c", cmd1 };
			cmdArrayImportSql = new String[] { "cmd.exe", "/c", cmd2 };
		} else {
			cmdArrayCreateDatabase = new String[] { "/bin/sh", "-c", cmd1 };
			cmdArrayImportSql = new String[] { "/bin/sh", "-c", cmd2 };
		}
		try {
			Process exec = Runtime.getRuntime().exec(cmdArrayCreateDatabase, null, new File(mysqlPath));
			exec.waitFor();
			Process exec2 = Runtime.getRuntime().exec(cmdArrayImportSql, null, new File(mysqlPath));
			exec2.waitFor();
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} catch (InterruptedException e) {
			e.printStackTrace();
			return null;
		}
		return "ok";
	}

	public static String init(String username, String password, String driver, String host, String database,
			String mysqlPath, String sqlPath) {
		return init(username, password, driver, host, null, database, mysqlPath, sqlPath, null, null);
	}

	public static String init(String password, String database, String mysqlPath, String sqlPath) {
		return init(null, password, null, null, null, database, mysqlPath, sqlPath, null, null);
	}
	
	public static String init(String username, String password, String database, String mysqlPath, String sqlPath) {
		return init(username, password, null, null, null, database, mysqlPath, sqlPath, null, null);
	}

	public static String updatePassword(String username, String password, String driver, String host, Integer port,
			String newPassword) {
		if (StrUtil.isBlank(username)) {
			username = "root";
		}
		if (StrUtil.isBlank(password)) {
			password = "123456";
		}
		if (StrUtil.isBlank(driver)) {
			driver = "com.mysql.cj.jdbc.Driver";
		}
		if (StrUtil.isBlank(host)) {
			host = "localhost";
		}
		if (port == null) {
			port = 3306;
		}
		String url = "jdbc:mysql://" + host + ":" + port + "/" + "mysql" + "?characterEncoding=" + "utf8"
				+ "&useSSL=false&allowPublicKeyRetrieval=true";
		String sql = "ALTER USER '${username}'@'${host}' IDENTIFIED BY '${newPassword}'";
		sql = sql.replace("${host}", host);
		sql = sql.replace("${username}", username);
		sql = sql.replace("${newPassword}", newPassword);
		System.out.println(sql);
		DataSource dataSource = new SimpleDataSource(url, username, password);
		Connection connection = null;
		try {
			connection = dataSource.getConnection();
			SqlExecutor.execute(connection, sql);
			SqlExecutor.execute(connection, "FLUSH PRIVILEGES");
		} catch (SQLException e) {
			String message = e.getMessage();
			if (message != null && message.startsWith("Access denied for user")
					&& message.endsWith("(using password: YES)")) {
				System.out.println("【密码错误】");
			} else {
				e.printStackTrace();
			}
		} finally {
			DbUtil.close(connection);
		}
		return "ok";
	}
}
